package com.mkyong.soa.client;

import java.io.IOException;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Set;

public class ClientNio {
	public static void main(String[] args) throws IOException {
		SocketChannel channel = SocketChannel.open();
		channel.configureBlocking(false);
		channel.connect(new SocketAddress() {
		});
		
		Selector selector = Selector.open();
		channel.register(selector, SelectionKey.OP_CONNECT);
		int nKeys = selector.select();
		
		SelectionKey sKey = null;
		if(nKeys > 0){
			Set<SelectionKey> keys = selector.selectedKeys();
			for(SelectionKey key:keys){
				if(key.isConnectable()){
					SocketChannel sc = (SocketChannel) key.channel();
					sc.configureBlocking(false);
					sc.finishConnect();
				}else if(key.isReadable()){
					ByteBuffer buffer = ByteBuffer.allocate(1024);
					SocketChannel sc = (SocketChannel) key.channel();
					int readBytes = 0;
					try {
						int ret = 0;
						try {
							while((ret=sc.read(buffer)) > 0){
								readBytes+=ret;
							}
						} catch (Exception e) {
							// TODO: handle exception
						}finally{
							buffer.flip();
						}
					} catch (Exception e) {
						// TODO: handle exception
					}finally{
						if(buffer != null){
							buffer.clear();
						}
					}
				}
				else if(key.isWritable()){
					ByteBuffer buffer = ByteBuffer.allocate(1024);
					key.interestOps(key.interestOps() & (~SelectionKey.OP_WRITE));
					SocketChannel sc = (SocketChannel) key.channel();
					int writtenedSize = sc.write(buffer);
					if(writtenedSize == 0){
						key.interestOps(key.interestOps() | SelectionKey.OP_WRITE);
					}
					selector.selectedKeys().clear();
				}
			ByteBuffer buffer = ByteBuffer.allocate(1024);
			int wSize = channel.write(buffer);
			if(wSize==0){
				key.interestOps(key.interestOps() | SelectionKey.OP_WRITE);
			}	
			}
			
		}
		
	}
}
